package mspbots.hubspot.client.core;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import mspbots.hubspot.client.core.client.HubSpotClient;
import mspbots.hubspot.common.RabbitKeys;
import mspbots.hubspot.common.ResultMsg;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.time.ZonedDateTime;

/**
 * mspbots.data.mspbots.data.hubspot.core.service.SyncService
 *
 * @author <a href="https://github.com/vnobo">Alex bob</a>
 * @date Created by 2020/7/10
 */
@Log4j2
public abstract class AbstractToolsUtil {

    protected ObjectMapper objectMapper;
    protected ReactiveStringRedisTemplate stringRedisTemplate;
    protected ReactiveRedisTemplate<String, Object> reactiveRedisTemplate;

    private RabbitMessagingTemplate rabbitMessagingTemplate;

    protected HubSpotClient hubSpotClient;

    protected Mono<Long> readAnchorTime(String key) {
        return this.stringRedisTemplate.opsForValue().get(key)
                .map(Long::parseLong)
                .defaultIfEmpty(ZonedDateTime.now().minusYears(20).toInstant().toEpochMilli());
    }

    protected void recordAnchorTime(String key, Long value) {
        this.readAnchorTime(key)
                .filter(v -> v < value)
                .flatMap(v -> this.stringRedisTemplate.opsForValue().set(key, value.toString(), Duration.ofDays(30)))
                .subscribe(result -> log.debug("Key {} record time {}", key, value),
                        err -> log.error(err.getMessage()));
    }

    protected void sendEntity(String key, ResultMsg resultMsg) {
        this.rabbitMessagingTemplate.convertAndSend(RabbitKeys.BASE_EXCHANGE_NAME, key, resultMsg);
    }

    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Autowired
    public void setStringRedisTemplate(ReactiveStringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Autowired
    public void setReactiveRedisTemplate(ReactiveRedisTemplate<String, Object> reactiveRedisTemplate) {
        this.reactiveRedisTemplate = reactiveRedisTemplate;
    }

    @Autowired
    public void setRabbitMessagingTemplate(RabbitMessagingTemplate rabbitMessagingTemplate) {
        this.rabbitMessagingTemplate = rabbitMessagingTemplate;
    }

    @Autowired
    public void setHubSpotClient(HubSpotClient hubSpotClient) {
        this.hubSpotClient = hubSpotClient;
    }
}
